#ifndef ADL_UART_H_
#define ADL_UART_H_

#include "target.h"


#define UART0	0
#define UART2	2
#define UART3	3

/*------------------- UART registers ------------------------*/
Sfr (SCON , 0x98);      
Sbit (SM0  , 0x98, 7);
Sbit (FE   , 0x98, 7);
Sbit (SM1  , 0x98, 6);
Sbit (SM2  , 0x98, 5);
Sbit (REN  , 0x98, 4);
Sbit (TB8  , 0x98, 3);
Sbit (RB8  , 0x98, 2);
Sbit (TI   , 0x98, 1);
Sbit (RI   , 0x98, 0);

Sfr (SBUF , 0x99);      
Sfr (SADEN , 0xB9);     
Sfr (SADDR , 0xA9);     





// Obs.: Before reading data, adl_uart_GET_LINE_STATUS must be called.
#define adl_uart_READ_RECEIVED_DATA(uart)	RBR(uart)

#define adl_uart_SEND_DATA(uart, data)	THR(uart) = data;

#define adl_uart_GET_BAUDRATE_DIVISOR(uart)	((U16)((DLM(uart) << 8) | (DLL(uart))))
// Obs.: Before set baudrate, divisor latch access muste be enabled (adl_uart_ENABLE_BAUDRATE_DLA)
#define adl_uart_SET_BAUDRATE_DIVISOR(uart, divisor)	DLL(uart) = (divisor & 0xFF);\
														DLM(uart) = (divisor >> 8);

#define adl_uart_GET_FRACTIONAL_BAUDRATE_DIVISOR(uart)			((*((FractionalDivisorRegister *)(&FDR(uart)))).DIVADDVAL)
#define adl_uart_SET_FRACTIONAL_BAUDRATE_DIVISOR(uart, divisor)	((*((FractionalDivisorRegister *)(&FDR(uart)))).DIVADDVAL = divisor)

#define adl_uart_GET_FRACTIONAL_BAUDRATE_MULTIPLIER(uart)				((*((FractionalDivisorRegister *)(&FDR(uart)))).MULVAL)
#define adl_uart_SET_FRACTIONAL_BAUDRATE_MULTIPLIER(uart, multiplier)	((*((FractionalDivisorRegister *)(&FDR(uart)))).MULVAL = multiplier)

#define adl_uart_ENABLE_RDA_INTERRUPT(uart)		(IER(uart) |= IER_RBR)
#define adl_uart_DISABLE_RDA_INTERRUPT(uart)	(IER(uart) &= ~(IER_RBR))
#define adl_uart_IS_ENABLE_RDA_INTERRUPT(uart)	(IER(uart) & IER_RBR)

#define adl_uart_ENABLE_THRE_INTERRUPT(uart)	(IER(uart) |= IER_THRE)
#define adl_uart_DISABLE_THRE_INTERRUPT(uart)	(IER(uart) &= ~(IER_THRE))
#define adl_uart_IS_ENABLE_THRE_INTERRUPT(uart)	(IER(uart) & IER_THRE)

#define adl_uart_ENABLE_RLS_INTERRUPT(uart)		(IER(uart) |= IER_RLS)
#define adl_uart_DISABLE_RLS_INTERRUPT(uart)	(IER(uart) &= ~(IER_RLS))
#define adl_uart_IS_ENABLE_RLS_INTERRUPT(uart)	(IER(uart) & IER_RLS)

#define adl_uart_GET_INTERRUPT_ID(uart)	((IIR(uart) >> 1) & 0x07)

#define adl_uart_GET_DATA_LENGTH(uart)			((*((LineControlRegister *)(&LCR(uart)))).wordLength)
#define adl_uart_SET_DATA_LENGTH(uart, setting)	((*((LineControlRegister *)(&LCR(uart)))).wordLength = setting)

#define adl_uart_GET_STOP_BIT(uart)				((*((LineControlRegister *)(&LCR(uart)))).stopBit)
#define adl_uart_SET_STOP_BIT(uart, setting)	((*((LineControlRegister *)(&LCR(uart)))).stopBit = setting)

#define adl_uart_IS_ENABLE_PARITY(uart)				((*((LineControlRegister *)(&LCR(uart)))).parityEnable)
#define adl_uart_SET_ENABLE_PARITY(uart, enable)	((*((LineControlRegister *)(&LCR(uart)))).parityEnable = enable)
#define adl_uart_GET_PARITY(uart)					((*((LineControlRegister *)(&LCR(uart)))).parity)
#define adl_uart_SET_PARITY(uart, setting)			((*((LineControlRegister *)(&LCR(uart)))).parity = setting)

#define adl_uart_ENABLE_BREAK_TRANSMISSION(uart)	((*((LineControlRegister *)(&LCR(uart)))).breakControl = 1)
#define adl_uart_DISABLE_BREAK_TRANSMISSION(uart)	((*((LineControlRegister *)(&LCR(uart)))).breakControl = 0)

#define adl_uart_ENABLE_BAUDRATE_DLA(uart)		((*((LineControlRegister *)(&LCR(uart)))).divisorLatchAccess = 1)
#define adl_uart_DISABLE_BAUDRATE_DLA(uart)		((*((LineControlRegister *)(&LCR(uart)))).divisorLatchAccess = 0)

#define adl_uart_IS_RECEIVE_DATA_READY(uart)	(LSR(uart) & LSR_RDR)

#define adl_uart_IS_OVERRUN_ERROR(uart)			(LSR(uart) & LSR_OE)

#define adl_uart_IS_PARITY_ERROR(uart)			(LSR(uart) & LSR_PE)

#define adl_uart_IS_FRAMING_ERROR(uart)			(LSR(uart) & LSR_FE)

#define adl_uart_IS_BREAK_INTERRUPT(uart)		(LSR(uart) & LSR_BI)

#define adl_uart_IS_TRANSMISSION_READY(uart)	(LSR(uart) & LSR_THRE)

#define adl_uart_IS_RX_FIFO_ERROR(uart)			(LSR(uart) & LSR_RXFE)


#endif /*ADL_UART_H_*/
